package com.yonyou.pmclouds.billview.config.aspect;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.entity.SuperVO;
import com.yonyou.pmclouds.basecom.exception.BusinessRuntimeException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.basecom.util.BeanHelper;
import com.yonyou.pmclouds.basecom.util.CommonFieldConst;
import com.yonyou.pmclouds.businessobject.rmiitf.BusinessObjectMaintain;
import com.yonyou.pmclouds.inspectitem.entity.InspectItemVO;
import com.yonyou.pmclouds.procedure.entity.ProcedureVO;
import com.yonyou.pmclouds.procedure.rmiitf.ProcedureQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Aspect
@Slf4j
@Component
public class BillFieldDataFillAspect {

    @Value("${print.businessObject.specialExtendTenant}")
    private String extendTenants;

    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private BusinessObjectMaintain businessObjectMaintain;

    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private ProcedureQuery procedureQuery;

    @Around("@annotation(com.yonyou.pmclouds.billview.config.aspect.PrintDataExtend)")
    public Object fillBillData(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object[] methodArgs = proceedingJoinPoint.getArgs();

        if (ArrayUtils.isEmpty(methodArgs) || !(methodArgs[0] instanceof SuperVO))
            throw new BusinessRuntimeException("使用@PrintDataExtend参数需要为SuperVO");

        SuperVO businessVO = (SuperVO) methodArgs[0];

        String tenantId = RuntimeEnvironment.getTenantId();

        if(StringUtils.isEmpty(tenantId)){
            tenantId =  BeanHelper.getProperty(businessVO, CommonFieldConst.PK_TENANT) == null ?
                    (String) BeanHelper.getProperty(businessVO, CommonFieldConst.PKTENANT) :
                    (String)BeanHelper.getProperty(businessVO, CommonFieldConst.PK_TENANT);
        }

        Object returnArg = proceedingJoinPoint.proceed();

        String pkProcedure = BeanHelper.getProperty(businessVO, CommonFieldConst.PK_PROCESS) == null ?
                (String) BeanHelper.getProperty(businessVO, CommonFieldConst.PKPROCESS) :
                (String)BeanHelper.getProperty(businessVO, CommonFieldConst.PK_PROCESS);

        if(StringUtils.isEmpty(extendTenants) || StringUtils.isEmpty(tenantId)||!extendTenants.contains(tenantId) || StringUtils.isEmpty(pkProcedure)){
            return returnArg;
        }

        ProcedureVO procedureVO = procedureQuery.getById(pkProcedure);

        if(procedureVO == null){
            return returnArg;
        }

        String printCode = businessObjectMaintain.getPrintCodeByProcessCode(procedureVO.getScode(), tenantId);

        if(StringUtils.isEmpty(printCode)){
            return returnArg;
        }

        Map<String, List<String>> attributeMap =  businessObjectMaintain.getAttrByProcedure(pkProcedure);
        if(attributeMap == null){
            return returnArg;
        }

        InspectItemVO[] inspectItemVOS =  (InspectItemVO[]) BeanHelper.getProperty(businessVO,CommonFieldConst.INSPECT_ITEMS);

        Map<String, Object> attributeDataMap = new HashMap<>();

        if(inspectItemVOS == null){
            return returnArg;
        }

        for (InspectItemVO inspectItemVO : inspectItemVOS) {
            List<String> attributeList = attributeMap.get(inspectItemVO.getPk_item());
            if(attributeList != null){
                Double[] datas = inspectItemVO.getDatas();
                if(datas != null && datas.length > 0){
                    for(int i = 0; i < datas.length; i++){
                        attributeDataMap.put(attributeList.get(i), datas[i]);
                    }
                }
            }
        }

        Map<String,Object[]> resultMap = (Map<String, Object[]>) returnArg;
        for(Map.Entry<String, Object[]> entry : resultMap.entrySet()){
            if(entry.getValue() == null || entry.getValue().length > 1){
                continue;
            }

            Object superVO = entry.getValue()[0];
            Class superVOClass = superVO.getClass();
            for(Field field : superVOClass.getDeclaredFields()){
                String key = field.getName();
                Object value = BeanHelper.getProperty(superVO, key);
                if(key.equalsIgnoreCase(CommonFieldConst.PROJECTNAME)){
                    key = CommonFieldConst.PROJECT_NAME;
                }else if(CommonFieldConst.CONSTRUCTION_NAME.equalsIgnoreCase(key)){
                    key = CommonFieldConst.CONSTRUCTIONUNIT_NAME;
                }
                attributeDataMap.put(key, value);
            }
        }

        Map<String, Object[]> newResultMap = new HashMap<>();

        newResultMap.put(procedureVO.getScode(), new Object[]{attributeDataMap});

        return newResultMap;
    }
}
